import { get, set } from 'lodash-es'

const childrenMap = new Map()
  .set('grid', 'columns')
  .set('tab', 'tabs')
  .set('collapse', 'data')

const positions = ['west', 'center', 'north', 'east','south', 'center.north', 'center.center']

// 收集链接表单事件集合
let linkFormGlobalExpression = [] 
// 收集链接表单规则集合
let linkFormRules = {
  calcRules: [],
  displayRules: [],
  modifyRules: [],
  requiredRules: [],
  validityRules: []
}

function getBaseCellStyle () {
  return {
    width: '25%',
    height: '35px',
    display: 'table-cell',
    borderStyle: 'solid',
    borderWidth: '1px',
    borderColor: '#ccc',
    background: '',
    borderTop: '',
    borderRight: '',
    borderLeft: '',
    borderBottom: '',
    fontSize: '14px',
    fontFamily: '微软雅黑',
    underline: false,
    fontStyle: 'normal' // 斜体-oblique
  }
}

/**
 * 页面模板转换
 * @param {Array} list 模板结构列表
 * @param {Object} widgets 控件信息列表映射（map) eg: "TEST.NAME": { key: "TEST.NAME", ...其它控件的配置信息}
 * @param {Boolean} isMerge true-合并；false-分离
 * @returns {Object} template 页面模板；widgets: 控件信息
 */
function transformTemplate(list, widgets = {}, isMerge = true, cb) {
  if (!Array.isArray(list)) {
    return {
      template: list,
      widgets
    }
  }
  const tableCellBaseStyle = getBaseCellStyle(); // 单元格基础样式
  const traverse = (list) => {
    const templateList = []
    if (!Array.isArray(list)) return []
    for (let index = 0; index < list.length; index++) {
      const w = list[index]
      const { type, key } = w
      const target = isMerge
        ? widgets[key] : {
          key,
          type
        }
      switch (type) {
      case 'table':
        for(let rowIndex = 0; rowIndex < w.data.length; rowIndex++) {
          for(let colIndex = 0; colIndex < w.data[rowIndex].length; colIndex ++) {
            const colItem = w.data[rowIndex][colIndex]
            colItem.select = false
            colItem.list = traverse(colItem.list)
            // 删除与基础单元格样式相同的样式数据
            const { style: tableCellStyleObj } = colItem;
            if (isMerge) {
              colItem.style = {
                ...tableCellBaseStyle,
                ...tableCellStyleObj
              }
            } else {
              for (const key in tableCellStyleObj) {
                if (tableCellBaseStyle[key] === tableCellStyleObj[key]) {
                  delete colItem.style[key];
                }
              }
            }
          }
        }
        target.data = w.data
        break;
      case 'easyLayout':
        for(let p = 0; p < positions.length; p++) {
          const children = get(w, positions[p], { list: [] })
          children.list = traverse(children.list)
          set(target, positions[p], children)
        }
        break
      default:
        if (childrenMap.has(type)) {
          const children = w[childrenMap.get(type)]
          for(let i = 0; i < children.length; i++) {
            children[i].list = traverse(children[i].list)
          }
          target[childrenMap.get(type)] = children
        }
      }
      // 分离模板和控件
      if (!isMerge) {
        if (!Reflect.has(widgets, key)) {
          widgets[key] = w
        }
      }
      const cbItem = isMerge ? target : w
      cb && cb (cbItem)
      templateList.push(target)
    }

    return templateList
  }
  const template = traverse(list)

  return {
    template,
    widgets
  }
}

/**
 *
 * @param {Array} list 控件列表
 * @param {Funtion} cb 回调函数
 * @param { Boolean } isHandleLinkForm 是否处理链接表单数据
 */
function traverseList(list, cb, brotherTableCell, isHandleLinkForm = true) {
  for (let index = 0; index < list.length; index++) {
    const widget = list[index]
    cb && cb(widget, brotherTableCell)
    const { type } = widget
    switch (type) {
    case 'table':
      for(let rowIndex = 0; rowIndex < widget.data.length; rowIndex++) {
        for(let colIndex = 0; colIndex < widget.data[rowIndex].length; colIndex ++) {
          const colItem = widget.data[rowIndex][colIndex]
          traverseList(colItem.list, cb, widget.data[rowIndex][colIndex - 1], isHandleLinkForm)
        }
      }
      break;
    case 'easyLayout':
      for(let p = 0; p < positions.length; p++) {
        const children = get(widget, positions[p])
        traverseList(children.list, cb, '', isHandleLinkForm)
      }
      break
    case 'linkForm':
      if(widget.list) {
        isHandleLinkForm && traverseList(widget.list, cb, '', isHandleLinkForm)
      }
      break
    default:
      if (childrenMap.has(type)) {
        const children = widget[childrenMap.get(type)]
        for(let i = 0; i < children.length; i++) {
          traverseList(children[i].list, cb, '', isHandleLinkForm)
        }
      }
    }
  }
}

// 格式化列表list
function formatList(list, type = 'pc') {
  let resultList = typeof list === 'string' ? JSON.parse(list) : list
  const isOver = Array.isArray(resultList)
  if (!isOver) {
    const { widgets, pcList, mbList } = resultList
    let template = []
    if (type === 'pc') {
      template = transformTemplate(pcList, widgets).template
    } else {
      template = transformTemplate(mbList, widgets).template
    }
    resultList = template
  }
  return resultList
}

/**
 * @description 处理链接表单控件list结构以及收集事件/规则
 * @param { Object } item 链接表单目标控件
 * @param { Object } parent 目标表单数据
 */
function linkFormList (item, parent) {
  const linktplid = item.options.linktplid
  let current = parent.linkedFormDataModel[linktplid]
  if (current) {
    // 处理控件链接表单list结构
    item.list = formatList(current.list) || []
    // 收集链接表单事件
    linkFormGlobalExpression = current.globalExpression ? [...linkFormGlobalExpression, ...JSON.parse(current.globalExpression)] : linkFormGlobalExpression
    // 收集链接表单规则
    const ruleGather = ['calcRules', 'displayRules', 'modifyRules', 'requiredRules', 'validityRules']
    const formRules = JSON.parse(current.formRules) || {}
    const isHasRules = Object.keys(formRules.formRules || {}).some(key => ruleGather.includes(key))
    if (isHasRules) {
      ruleGather.forEach(item => {
        linkFormRules[item] = [...linkFormRules[item], ...formRules.formRules[item]]
      })
    }
    // 处理嵌套链接表单
    linkFormControls(item.list, current)
  } else {
    item.list = []
  }
}

/**
 * @description 处理tab控件数据
 * @param { Object } itm 目标控件
 */
function handleTabItem (itm) {
  if (!('key' in itm)) {
    itm.key = itm.id;
  }

  if (!('defaults' in itm)) {
    itm.defaults = false;
  }

  if (!('options' in itm)) {
    itm.options = {
      permission: ['edit']
    }
  }
}

/**
 * @description 处理控件list循环
 * @param { Array } formList list结构
 * @param { Object } formData 表单数据
 * @param { String } type 表单选择控件标识
 */
function linkFormControls (formList, formData, type) {
  traverseList(formList, (item) => {
    if (type === 'generateFormSelect' && item.options && item.options.permission) { // 表单选择控件设置权限
      item.options.permission = ['edit'];
    }
    if (item.type === 'linkForm') {
      linkFormList(item, formData)
    }
    if (item.type === 'tab') {
      item.tabs.map(itm => {
        handleTabItem(itm)
      })
    }
  }, '', false)
}

/**
 * @description 初始化事件及规则集合
 */
function initLinkFormData() {
  linkFormGlobalExpression = []
  linkFormRules = {
    calcRules: [],
    displayRules: [],
    modifyRules: [],
    requiredRules: [],
    validityRules: []
  }
}

/**
 * @description 处理链接表单list、事件、规则
 * @param { Object } formData 表单数据
 * @param { String } type 表单选择控件标识
 * @param { Boolean } isSingle 是否为单表单
 * @returns { Object } formData 表单数据
 */
export function handleLinkFormList(formData, type, isSingle) {
  initLinkFormData() // 初始化事件及规则集合
  if (formData) {
    let formDataModelMapData = formData.formDataModelMap ? formData.formDataModelMap : formData.formDataModel.formDataModelMap ? formData.formDataModel.formDataModelMap : {}
    for (let index in formDataModelMapData) {
      const formItem = formDataModelMapData[index]
      // 处理链接表单list结构
      const formList = formItem.list ? formatList(formItem.list) : []
      linkFormControls(formList, formItem, type)
      formItem.list = formList
      // 处理链接表单事件
      const formGlobalExpression = formItem.globalExpression ? JSON.parse(formItem.globalExpression) : []
      formItem.globalExpression = JSON.stringify([...formGlobalExpression, ...linkFormGlobalExpression])
      // 处理链接表单规则
      const ruleGather = ['calcRules', 'displayRules', 'modifyRules', 'requiredRules', 'validityRules']
      // 兼容表单规则数据
      const formRules = JSON.parse(formItem.formRules) || {}
      formRules.formRules = formRules.formRules || {}
      const isHasRules = Object.keys(formRules.formRules).some(key => ruleGather.includes(key))
      ruleGather.forEach(item => {
        if (!(item in formRules.formRules)) formRules.formRules[item] = []
        formRules.formRules[item] = isHasRules ? [...formRules.formRules[item], ...linkFormRules[item]] : linkFormRules[item]
      })
      formItem.formRules = JSON.stringify(formRules)
      // 删除链接表单数据
      formItem.linkedFormDataModel = {}
    }
    // 处理外部表单数据
    const formOutsideData = formData.formDataModelMap ? formData : formData.formDataModel

    // 兼容空表单情况
    if (formDataModelMapData && formDataModelMapData[formOutsideData.rid]) {
      formOutsideData.list = formDataModelMapData[formOutsideData.rid].list
      formOutsideData.globalExpression = formDataModelMapData[formOutsideData.rid].globalExpression
      formOutsideData.formRules = formDataModelMapData[formOutsideData.rid].formRules
      if (isSingle) {
        //赋值后删除里面表单list数据
        formDataModelMapData[formOutsideData.rid].list = {};
      }
    }

    // 删除链接表单数据
    formOutsideData.linkedFormDataModel = {}
  }
  return formData
}
